!function (w) {
  let nullFun = function (cb) { console.log("no heyhey"); };
  var protocol = {
    call: {
      setTopBarShare: "topBar:share",
      setTopBarExplain: "topBar:explain",
      heyheytalkPath: "heyheytalk://",
      openShareBar: "shareBar:open",
      shareToHHmessage: "shareTo:hhmessage",
      shareToWXtimeline: "shareTo:wxtimeline",
      shareToWXmessage: "shareTo:wxmessage",
      shareToQQ: "shareTo:qq",
      shareToQzone: "shareTo:qzone",
      getHeyid: "get:heyid",
      getToken: "get:token",
      request: "server:request",
      getUserIdAndRoom: "get:userroom",
      heyDo: "hey:do"
    },
    // event:{
    //     onShareHHMessage: "share:hhmessage",
    //     onShareWxTimeline: "share:wxtimeline",
    //     onShareWxMessage: "share:wxmessage",
    //     onShareQQ: "share:qq",
    //     onShareQZone: "share:qzone"
    // }
    event: {
      onShareHHMessage: "share:hhmessage",
      onShareWxTimeline: "share:wxtimeline",
      onShareWxMessage: "share:wxmessage",
      onShareQQ: "share:qq",
      onShareQZone: "share:qzone",
      onPaySuccess: "pay:succ"
    }
  };
  var h = {};
  var eventMap = {};
  for (key in protocol.event) {
    !function () {
      var action = protocol.event[key];
      h[key] = function (cb) {
        eventMap[action] = function (data) {
          cb(data);
        };
      };
    }();
  };
  for (key in protocol.call) {
    h[key] = nullFun;
  };
  function setupEvent(callFun, configData) {
    for (key in protocol.call) {
      !function () {
        var action = protocol.call[key];
        h[key] = function (data, cb) {
          callFun(action, data, cb);
        };
      }();
    };
    configData.onShareHHMessage && h.onShareHHMessage(configData.onShareHHMessage);
    configData.onShareWxTimeline && h.onShareWxTimeline(configData.onShareWxTimeline);
    configData.onShareWxMessage && h.onShareWxMessage(configData.onShareWxMessage);
    configData.onShareQQ && h.onShareQQ(configData.onShareQQ);
    configData.onShareQZone && h.onShareQZone(configData.onShareQZone);
    configData.onPaySuccess && h.onPaySuccess(configData.onPaySuccess);
  }
  var callHander = function (data, responseCallback) {
    if (typeof data === 'string') {
      data = JSON.parse(data);
    }
    // 接口定义问题
    var event = eventMap[data.action || data.a];
    if (!event) {
      responseCallback({ 'result': 201 });
      return;
    }
    event(data.data);
    responseCallback({ 'result': 0 });
  };

  function setupHeyHeyJSBridge(callback) {
    if (window.WebViewJavascriptBridge) {
      return callback(WebViewJavascriptBridge);
    }
    if (window.WVJBCallbacks) {
      return window.WVJBCallbacks.push(callback);
    }
    document.addEventListener('WebViewJavascriptBridgeReady', function () {
      // callback(WebViewJavascriptBridge)
      WVJBCallbacks.forEach(function (cb) {
        cb(WebViewJavascriptBridge);
      })
    }, false);

    window.WVJBCallbacks = [callback];
    var WVJBIframe = document.createElement('iframe');
    WVJBIframe.style.display = 'none';
    WVJBIframe.src = 'https://__bridge_loaded__';
    document.documentElement.appendChild(WVJBIframe);
    setTimeout(function () { document.documentElement.removeChild(WVJBIframe) }, 0);
  }


  w.Heyhey = h;
  h.config = function (configData, configCb) {
    setupHeyHeyJSBridge(function (bridge) {
      bridge.registerHandler('HeyHeyToJSBridge', function (data, responseCallback) {
        callHander(data, responseCallback);
      });
      const timeLong = 1000;
      var callFun = function (action, data, cb) {
        var end = false;
        var out = setTimeout(function () {
          if (!end) {
            console.log(`jsbrage timeout..., action: ${action}, data: ${JSON.stringify(data)}, timeLong: ${timeLong}`);
            end = true;
            cb && cb(null);
          }
        }, timeLong);
        console.log('call start action:', action, data, bridge)
        bridge.callHandler('JSToHeyHeyBridge', { 'action': action, 'data': data }, function (response) {
          console.log('call end action:', action, data)
          if (!end) {
            end = true;
            clearTimeout(out);
            cb && cb(response);
          }
        });
      };
      setupEvent(callFun, configData);
      configCb && configCb();
    });
  };
}(this);

window.isHeyHeyTalk = () => {
  if (window.navigator.userAgent.toLowerCase().match(/heyheytalk/i) == 'heyheytalk') {
    return true;
  }
  return false;
}
